package main

import (
	"context"
	"fmt"
	"os"
	"time"

	"gitee.com/libs_2/ewelinkapi"
	"gitee.com/libs_2/ewelinkapi/cache"
	"gitee.com/libs_2/ewelinkapi/model"
	"github.com/redis/go-redis/v9"
)

var (
	client         *ewelinkapi.Client
	phone          = "+86185***"
	pwd            = "aaaa1234"
	domain         = "https://cn-apia.coolkit.cn"
	dispatchDomain = "https://cn-dispa.coolkit.cn/dispatch/app"
	appId          = "***"
	secret         = "***"
	// 易微联用户id
	controlerApiKey = "***"
	hostApiKey      = "***"
	deviceId        = "***"
	accessToken     = "***"
	refreshToken    = "***"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "192.168.31.101:6379",
		Password: "", // no password set
		DB:       1,  // use default DB
	})

	r := rdb.Ping(ctx)
	if r.Err() != nil {
		panic(r.Err())
	}

	cache := cache.NewRedis(rdb)
	client = ewelinkapi.NewClient(domain, dispatchDomain, appId, secret, cache)
	client.SetAutoToken(true, ewelinkapi.WithAccount(model.AccountLoginRequest{
		Lang:        "cn",
		CountryCode: "+86",
		PhoneNumber: phone,
		Password:    pwd,
	}))

	interrupt := make(chan os.Signal, 1)
	dr, err := client.GetDispatchInfo(ctx)
	if err != nil {
		panic(err)
	}

	// 注册回调
	client.UseDeviceUpdateState(OnDeviceUpdateState)
	client.UseDeviceOnlineStateChange(OnDeviceOnlineStateChange)
	client.UseOnConnectionClose(OnConnectionClose)

	// 发起握手，启动websocket
	client.Handshake(ctx, interrupt, dr, controlerApiKey)

	timer := time.NewTicker(10 * time.Second)
	for {
		select {
		case <-timer.C:
			client.Outlet4QueryStateBySocket(ctx, model.QueryOutlet4Request{
				Action:     "query",
				Apikey:     hostApiKey,
				SelfApikey: controlerApiKey,
				Deviceid:   deviceId,
				UserAgent:  "app",
				Sequence:   time.Now().UnixMicro(),
				Params:     []string{"switches", "timers"},
			})
		}
	}
}

func OnConnectionClose(interrupt <-chan os.Signal) {
	timer := time.NewTicker(5 * time.Second)
	for {
		if client.GetSocketIsRun() {
			return
		}

		select {
		case <-timer.C:
			if client.GetSocketIsRun() {
				return
			}

			ctx := context.Background()
			client.ReConnect(ctx, interrupt, controlerApiKey)
		}
	}
}

func OnDeviceOnlineStateChange(msg model.NotifyDeviceOnline) {
	fmt.Printf("OnDeviceOnlineStateChange:%#v\n", msg)
}

func OnDeviceUpdateState(msg model.NotifyOutlet4Update) {
	fmt.Printf("OnDeviceUpdateState:%#v\n", msg)
}
